﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.ComponentModel.Composition;
using Bzure.Common.Composition;

namespace Bzure.Mvc.Controllers
{
    public class ThemeControllerFactory : DefaultControllerFactory
    {
        class ControllerContainer : MEFContainerBase
        {
            [ImportMany]
            public IEnumerable<PartFactory<IController, IControllerMetadata>> ControllerFactories;
            //protected override string MapPath(string virtualPath)
            //{
            //    return HttpContext.Current.Server.MapPath(virtualPath);
            //}
        }
        ControllerContainer ControllerBox;
        public ThemeControllerFactory()
        {
            ControllerBox = new ControllerContainer();
            ControllerBox.Compose();
        }

        /// <summary>
        /// Creates an instance of a controller for the specified name.
        /// </summary>
        /// <param name="requestContext">The current request context.</param>
        /// <param name="controllerName">The name of the controller.</param>
        /// <returns>An instance of a controller for the specified name.</returns>
        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            string areaName = AreaHelpers.GetAreaName(requestContext.RouteData);
            if (string.IsNullOrEmpty(areaName))
            {
                areaName = Actor.Public.DefaultArea();
                requestContext.RouteData.DataTokens["area"] = areaName;
            }
            var factory = this.ControllerBox.ControllerFactories
                .Where(f => f.Metadata.Name.Equals(controllerName, StringComparison.InvariantCultureIgnoreCase) && f.Metadata.Area.Equals(areaName, StringComparison.InvariantCultureIgnoreCase))
                .FirstOrDefault();

            if (factory != null)
                return factory.CreatePart();

            try
            {
                return base.CreateController(requestContext, controllerName);
            }
            catch (Exception e)
            {
                return null;
            }
        }
    }
}
